package com.app.weexlearnmodule.adapter;

import android.util.Log;

import com.app.weexlearnmodule.IncrementaRequestBody;
import com.app.weexlearnmodule.IncrementalResponseBody;
import com.app.weexlearnmodule.listener.RequestListener;
import com.app.weexlearnmodule.listener.ResponseListener;
import com.taobao.weex.adapter.IWXHttpAdapter;
import com.taobao.weex.common.WXRequest;
import com.taobao.weex.common.WXResponse;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class InterceptWXHttpAdapter implements IWXHttpAdapter {

    private static final String TAG = InterceptWXHttpAdapter.class.getSimpleName();

    private static final String METHOD_GET = "GET";
    private static final String METHOD_POST = "POST";

    public static final int REQUEST_FAILURE = -100;

    @Override
    public void sendRequest(final WXRequest request, final OnHttpListener listener) {
        Log.i(TAG, "sendRequest: listener -> " + listener + ":::request -> " + request.url);
        if (listener != null) {
            listener.onHttpStart();
        }

        RequestListener requestListener = new RequestListener() {
            @Override
            public void onRequest(long consumed, long total, boolean done) {
                if(listener != null){
                    listener.onHttpUploadProgress((int) (consumed));
                }
            }
        };

        final ResponseListener responseListener = new ResponseListener() {
            @Override
            public void onResponse(long consumed, long total, boolean done) {
                if(listener != null){
                    listener.onHttpResponseProgress((int) (consumed));
                }
            }
        };

        OkHttpClient.Builder build = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Log.i(TAG, "intercept: 111111");
                Response originalResponse = null;

                Response response = null;
                try {
                    originalResponse = chain.proceed(chain.request());

                    response = originalResponse.newBuilder()
                            .body(new IncrementalResponseBody(originalResponse.body(), responseListener))
                            .build();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Log.i(TAG, "intercept: response -> " + response);
                return response == null ? originalResponse : response;
            }
        });

        OkHttpClient client = null;

        try {

            client = build.build();
        } catch (Exception e) {
            e.printStackTrace();
            Log.i(TAG, "sendRequest: e--->" + e.getMessage());
            return;
        }

        if(METHOD_GET.equalsIgnoreCase(request.method)){
            Request okHttpRequest = new Request.Builder().url(request.url).build();
            client.newCall(okHttpRequest).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    if(listener != null){
                        WXResponse wxResponse = new WXResponse();
                        wxResponse.errorCode = String.valueOf(REQUEST_FAILURE);
                        wxResponse.statusCode = String.valueOf(REQUEST_FAILURE);
                        wxResponse.errorMsg = e.getMessage();
                    }
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if(listener != null){

                        WXResponse wxResponse = new WXResponse();
                        wxResponse.statusCode = String.valueOf(response.code());
                        if(requestSuccess(Integer.parseInt(wxResponse.statusCode))){
                            wxResponse.originalData = response.body().bytes();
                        }else {
                            wxResponse.errorCode = String.valueOf(response.code());
                            wxResponse.errorMsg = response.body().string();
                        }

                        listener.onHttpFinish(wxResponse);
                    }
                }
            });
        }else if(METHOD_POST.equalsIgnoreCase(request.method)){
            Request okHttpRequest = new Request.Builder()
                    .url(request.url)
                    .post(new IncrementaRequestBody(RequestBody.create(MediaType.parse(request.body),request.body),requestListener))
                    .build();

            client.newCall(okHttpRequest).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    if(listener != null){
                        WXResponse wxResponse = new WXResponse();
                        wxResponse.errorCode = String.valueOf(REQUEST_FAILURE);
                        wxResponse.statusCode = String.valueOf(REQUEST_FAILURE);
                        wxResponse.errorMsg = e.getMessage();
                    }
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if(listener != null){

                        WXResponse wxResponse = new WXResponse();
                        wxResponse.statusCode = String.valueOf(response.code());
                        if(requestSuccess(Integer.parseInt(wxResponse.statusCode))){
                            wxResponse.originalData = response.body().bytes();
                        }else {
                            wxResponse.errorCode = String.valueOf(response.code());
                            wxResponse.errorMsg = response.body().string();
                        }

                        listener.onHttpFinish(wxResponse);
                    }
                }
            });
        }
    }

    private boolean requestSuccess(int statusCode) {
        return statusCode >= 200 && statusCode <= 299;
    }
}
